#include<stdio.h>
#include <windows.h>
#include <time.h>
#include <stdbool.h>
#include<string.h>
#include <math.h>
#include <stdlib.h>

#define PI 3.14159265358979323846
#define RAD (M_PI/180.0)
// 农历数据结构
typedef struct {
    int year;
    int month;
    int day;
    int isLeapMonth;
} LunarDate;

// 节气数据结构
typedef struct {
    char name[20];
    int month;
    int day;
    int solarYear;
} SolarTerm;

// 公历节日结构体
typedef struct {
    int month;
    int day;
    char name[50];
} SolarFestival;

// 农历节日结构体
typedef struct {
    int month;
    int day;
    char name[50];
} LunarFestival;
// 农历年份信息结构体
typedef struct {
    int year;           // 农历年份
    int monthCount;     // 该年农历月数(12或13)
    int newYearMonth;   // 正月初一对应的公历月份
    int newYearDay;     // 正月初一对应的公历日
    int leapMonth;      // 闰月月份(0表示无闰月)
    int monthDays[13];  // 每月天数(从正月开始)
} LunarYearInfo;

// 全局变量
SolarTerm solarTerms[24];
const char* termNames[] = {
    "小寒", "大寒", "立春", "雨水", "惊蛰", "春分",
    "清明", "谷雨", "立夏", "小满", "芒种", "夏至",
    "小暑", "大暑", "立秋", "处暑", "白露", "秋分",
    "寒露", "霜降", "立冬", "小雪", "大雪", "冬至"
};

// 天干名称
const char* TianGan[] = {"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"};

// 地支名称
const char* DiZhi[] = {"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"};

// 公历月份天数(非闰年)
const int gregorianMonthDays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

// 农历年份信息表 
LunarYearInfo lunarYearTable[] = {
	{2000, 5, 29, 11, 1, {30, 29, 30, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30}},
    {2001, 4, 30, 11, 1, {29, 30, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29}},
    {2002, 0, 0, 11, 0, {30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29}},
    {2003, 3, 29, 11, 1, {29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30}},
    {2004, 2, 30, 11, 1, {30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30}},
    {2005, 0, 0, 11, 0, {29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30}},
    {2006, 7, 30, 11, 1, {30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29}},
    {2007, 6, 29, 11, 1, {29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30}},
    {2008, 0, 0, 11, 0, {30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29}},
    {2009, 5, 29, 11, 1, {29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30}},
    {2010, 4, 30, 11, 1, {30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29}},
    {2011, 0, 0, 11, 0, {29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30}},
    {2012, 4, 30, 11, 1, {30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29}},
    {2013, 3, 29, 11, 1, {29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30}},
    {2014, 9, 30, 11, 1, {30, 29, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29}},
    {2015, 6, 29, 11, 1, {29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30}},
    {2016, 0, 0, 11, 0, {30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29}},
    {2017, 6, 29, 11, 1, {29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30}},
    {2018, 4, 30, 11, 1, {30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29}},
    {2019, 0, 0, 11, 0, {29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30}},
    {2020, 4, 30, 11, 1, {30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29}},
    {2021, 12, 2, 12, 0, {29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29}},
    {2022, 2, 29, 11, 1, {30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30}},
    {2023, 3, 30, 11, 1, {29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30}},
    {2024, 6, 29, 11, 1, {30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29}},
    {2025, 7, 30, 11, 1, {29, 30, 29, 30, 29, 30, 30, 30, 29, 30, 29, 30, 29}},
    {2026, 5, 29, 11, 1, {30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29}},
    {2027, 4, 30, 11, 1, {29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30}},
    {2028, 6, 29, 11, 1, {30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29}},
    {2029, 5, 30, 11, 1, {29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30}},
    {2030, 3, 29, 11, 1, {30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30}},
    {2031, 3, 30, 11, 1, {29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30}},
    {2032, 6, 29, 11, 1, {30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29}},
    {2033, 11, 29, 12, 1, {29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30}},
    {2034, 10, 30, 11, 1, {30, 29, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29}},
    {2035, 8, 29, 11, 1, {29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30}},
    {2036, 6, 30, 11, 1, {30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29}},
    {2037, 5, 29, 11, 1, {29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30}},
    {2038, 4, 30, 11, 1, {30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29}},
    {2039, 3, 29, 11, 1, {29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30}},
    {2040, 7, 30, 11, 1, {30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29}},
    {2041, 6, 29, 11, 1, {29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30}},
    {2042, 4, 30, 11, 1, {30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29}},
    {2043, 3, 29, 11, 1, {29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30}},
    {2044, 5, 30, 11, 1, {30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29}},
    {2045, 4, 29, 11, 1, {29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30}},
    {2046, 3, 30, 11, 1, {30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30}},
    {2047, 7, 29, 11, 1, {29, 30, 29, 30, 29, 30, 30, 30, 29, 30, 29, 30, 29}},
    {2048, 6, 30, 11, 1, {30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29}},
    {2049, 4, 29, 11, 1, {29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30}},
    {2050, 3, 30, 11, 1, {30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30}},
    {0, 0, 0, 0, 0, {0}}  // 结束标记
};

// 函数声明
void Lunar();
void queryLunarCalendar();
double julian_day(int year, int month, double day);
double solar_longitude(double JD);
void Solar(int year, int index, int *month, int *day);
void calculateSolarTerms(int year);
int findNextSolarTerm(int year, int month, int day, SolarTerm *nextTerm);
void displaySolarTerms(int year, int month);
bool isLeapYear(int year);
int getDaysInMonth(int year, int month);
int getTotalDays(int year, int month);
void Month(int year, int month);
void solarToLunar(int year, int month, int day, LunarDate *lunar);
void getGanZhi(int year, int month, int day, char *ganzhi);
void calculate_date(int days, int *year, int *month, int *day);
const char* get_weekday_name(int year, int month, int day) ;
int Todaydistancedate() ;
void setColor(int color);
void showSolarFestival(int month);
void showLunarFestivals() ;
int Festival();
void DayTodayDistance();
void DayDayDistance();
void GetCurTime(char *timeStr) ;
int GetGregorianMonthDays(int year, int month);
bool IsValidLunarDate(int year, int month, int day);
void GetGanZhiYear(int lunarYear, char* ganZhi);
bool GetGre(int lunarYear, int lunarMonth, int lunarDay, int* greYear, int* greMonth, int* greDay);
void ShowMainMenu();
void LunarToGregorian() ;
int main()
{
	char timeStr[26];
	int n,year,month,day,y1,m1,d1,y2,m2,d2;
    GetCurTime(timeStr);
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
    printf("\n\n\n");
	printf("----------------------------------------------\n");
	printf("|              欢迎使用万年历                |\n");
	printf("----------------------------------------------\n");
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
    printf("当前时间: %s\n", timeStr);
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
	printf("|                 1-查询农历                   |\n\n");
	printf("|                 2-查询公历                   |\n\n");
	printf("|                 3-显示月历                   |\n\n");
	printf("|           4-查询某天距今天的天数             |\n\n");
	printf("|         5-查询距今天相应天数的日期           |\n\n");
	printf("|         6-查询任意两天之间的天数差           |\n\n");
	printf("|               7-显示二十四节气               |\n\n");
	printf("|                 8-显示节日                   |\n\n");
	printf("|                 0-退出程序                   |\n\n");
	printf("----------------------------------------------\n");
	
	while(1)
	{
		printf("请输入你的选择：");
		scanf("%d",&n);
		switch(n)
	{
		case 1:
			{
				Lunar();
				break;
			}
		case 2:
			{
				int choice;
    
    while (1) {
        ShowMainMenu();
        if (scanf("%d", &choice) != 1) {
            printf("输入无效!\n");
            while (getchar() != '\n'); // 清除输入缓冲区
            continue;
        }
        
        switch (choice) {
            case 1:
                LunarToGregorian();
                break;
            case 2:
                printf("\n感谢使用，再见!\n");
                exit(0);
            default:
                printf("\n无效的选项，请重新输入!\n");
                while (getchar() != '\n'); // 清除输入缓冲区
        }
        break;
    }
    break;
			}
		case 3:
		{
			printf("请输入要查询的年月");
			scanf("%d%d",&year,&month);
			if (year < 1900 || month < 1 || month > 12) {
        printf("输入无效! 年份应大于等于1900，月份应在1-12之间。\n");
        return 1;
    }
			Month(year,month);break;
		}
		case 4:
			{
				DayTodayDistance();
				break;
			}
		case 5:
			{
				Todaydistancedate();
				break;
			}
		case 6:
			{
                DayDayDistance();
                break;
			}
		case 7:
		{
			
			int year;
    printf("请输入要查询的年份: ");
    scanf("%d", &year);
    
    if (year < 1900 || year > 2100) {
        printf("年份超出范围(1900-2100)\n");
        return 1;
    }
    
    const char *solar_terms[] = {
        "小寒", "大寒", "立春", "雨水", "惊蛰", "春分",
        "清明", "谷雨", "立夏", "小满", "芒种", "夏至",
        "小暑", "大暑", "立秋", "处暑", "白露", "秋分",
        "寒露", "霜降", "立冬", "小雪", "大雪", "冬至"
    };
    
    printf("%d年的二十四节气:\n", year);
    printf("============================\n");
    
    for (int i = 0; i < 24; i++) {
        int month, day;
        Solar(year, i, &month, &day);
        printf("%2d月 %2d日: %s\n", month, day-3, solar_terms[i]);
    }
			break;
			}	
		case 8 :
		{
			Festival();
			break;
		}
		case 0:return 0;
		default:printf("error");
	}
	}
	return 0;
}
void Lunar() {
    int choice;
    
    while (1) {
        printf("\n========== 农历查询系统 ==========\n");
        printf("1. 查询农历\n");
        printf("0. 退出系统\n");
        printf("请输入您的选择: ");
        scanf("%d", &choice);
        
        switch (choice) {
            case 1:
                queryLunarCalendar();
                break;
            case 0:
                printf("感谢使用，再见！\n");
                break;
            default:
                printf("无效的输入，请重新选择！\n");
        }
        break;
    }
}
// 精确计算儒略日
// 查询农历界面
void queryLunarCalendar() {
    int year, month, day;
    LunarDate lunar;
    char ganzhi[50];
    SolarTerm nextTerm;
    int daysToNextTerm;
    
    printf("\n========== 农历查询 ==========\n");
    printf("请输入公历日期(年 月 日，用空格分隔): ");
    scanf("%d %d %d", &year, &month, &day);
    
    // 1. 显示当月月历
    printf("\n1. 查询日期所在的当月月历:\n");
    Month(year, month);
    
    // 2. 计算并显示天干地支
    solarToLunar(year, month, day, &lunar);
    getGanZhi(year, month, day, ganzhi);
    printf("\n2. 天干地支: %s\n", ganzhi);
    
    // 3. 判断是否是节气
    calculateSolarTerms(year);
    daysToNextTerm = findNextSolarTerm(year, month, day, &nextTerm);
    
    printf("\n3. 节气信息:\n");
    if (daysToNextTerm == 0) {
        printf("今天是节气: %s\n", nextTerm.name);
    } else {
        printf("今天不是节气，距离下一个节气 %s 还有 %d 天\n", nextTerm.name, daysToNextTerm);
    }
    
    // 4. 显示当月的节气日期
    printf("\n4. 当月的节气日期:\n");
    displaySolarTerms(year, month);
}
double julian_day(int year, int month, double day) {
    if (month <= 2) {
        year--;
        month += 12;
    }
    int A = year / 100;
    int B = 2 - A + A / 4;
    return floor(365.25 * (year + 4716)) + floor(30.6001 * (month + 1)) + day + B - 1524.5;
}

// 精确太阳黄经计算
double solar_longitude(double JD) {
    double T = (JD - 2451545.0) / 36525.0;
    
    // 太阳平黄经(度)
    double L0 = 280.46645 + 36000.76983 * T;
    
    // 太阳平近点角(度)
    double M = 357.52910 + 35999.05030 * T;
    
    // 地球轨道偏心率
    double e = 0.016708617 - 0.000042037 * T;
    
    // 中心差(度)
    double C = (1.914600 - 0.004817 * T) * sin(M * RAD) 
             + (0.019993 - 0.000101 * T) * sin(2 * M * RAD)
             + 0.000290 * sin(3 * M * RAD);
    
    // 太阳真黄经(度)
    double L = L0 + C;
    
    // 确保在0-360度范围内
    L = fmod(L, 360.0);
    if (L < 0) L += 360.0;
    
    return L;
}

// 计算节气日期
void Solar(int year, int index, int *month, int *day) {
    const double term_angles[] = {
        285.0, 300.0, 315.0, 330.0, 345.0, 0.0,
        15.0, 30.0, 45.0, 60.0, 75.0, 90.0,
        105.0, 120.0, 135.0, 150.0, 165.0, 180.0,
        195.0, 210.0, 225.0, 240.0, 255.0, 270.0
    };
    
    double target_lng = term_angles[index];
    int est_month = (index + 1) / 2 + 1; // 估算月份
    
    double JD = julian_day(year, est_month, 15); // 从月中开始搜索
    double last_JD = JD;
    
    // 迭代寻找精确日期
    for (int i = 0; i < 50; i++) {
        double L = solar_longitude(JD);
        double delta = fmod(L - target_lng + 180.0, 360.0) - 180.0;
        
        // 调整步长
        double step = delta / 360.0 * 365.25;
        if (fabs(step) > 10.0) step = (step > 0) ? 10.0 : -10.0;
        
        last_JD = JD;
        JD -= step;
        
        // 检查收敛
        if (fabs(delta) < 0.1) break;
    }
    
    // 转换为公历日期
    JD += 0.5;
    int Z = (int)JD;
    double F = JD - Z;
    
    int A = (Z < 2299161) ? Z : (Z + 1 + (int)((Z - 1867216.25) / 36524.25));
    int B = A + 1524;
    int C = (int)((B - 122.1) / 365.25);
    int D = (int)(365.25 * C);
    int E = (int)((B - D) / 30.6001);
    
    *day = (int)(B - D - (int)(30.6001 * E) + F);
    *month = (E < 14) ? (E - 1) : (E - 13);
    
}

void calculateSolarTerms(int year) {
    for (int i = 0; i < 24; i++) {
        Solar(year, i, &solarTerms[i].month, &solarTerms[i].day);
        strcpy(solarTerms[i].name, termNames[i]);
        solarTerms[i].solarYear = year;
    }
}

// 查找下一个节气
int findNextSolarTerm(int year, int month, int day, SolarTerm *nextTerm) {
    int currentJD = (int)julian_day(year, month, day);
    int minDays = 365;
    int nextIndex = -1;
    
    for (int i = 0; i < 24; i++) {
        int termJD = (int)julian_day(solarTerms[i].solarYear, solarTerms[i].month, solarTerms[i].day);
        int diff = termJD - currentJD;
        
        if (diff > 0 && diff < minDays) {
            minDays = diff;
            nextIndex = i;
        }
    }
    
    if (nextIndex == -1) {
        // 如果今年没有下一个节气，查找明年的第一个节气
        calculateSolarTerms(year + 1);
        nextIndex = 0;
        minDays = (int)julian_day(year+1, solarTerms[0].month, solarTerms[0].day) - currentJD;
    }
    
    *nextTerm = solarTerms[nextIndex];
    
    return (minDays == 0) ? 0 : minDays-4;
}

// 显示当月的节气
void displaySolarTerms(int year, int month) {
    int found = 0;
    
    for (int i = 0; i < 24; i++) {
        if (solarTerms[i].month == month && solarTerms[i].solarYear == year) {
            printf("%s: %d月%d日\n", solarTerms[i].name, month, solarTerms[i].day-4);
            found = 1;
        }
    }
    
    if (!found) {
        printf("本月没有节气\n");
    }
}
void GetCurTime(char *timeStr) {
    time_t now;
    struct tm *current_time;
    time(&now);
    current_time = localtime(&now);
    strftime(timeStr, 26, "%Y-%m-%d %H:%M:%S", current_time);
}
// 判断是否为闰年
bool isLeapYear(int year) {
    return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}

// 获取某年某月的天数
int getDaysInMonth(int year, int month) {
    if (month == 2) {
        return isLeapYear(year) ? 29 : 28;
    } else if (month == 4 || month == 6 || month == 9 || month == 11) {
        return 30;
    } else {
        return 31;
    }
}

// 计算从1900年1月1日到指定日期的总天数
int getTotalDays(int year, int month) {
    int totalDays = 0;
    
    // 计算1900年到year-1年的总天数
    for (int y = 1900; y < year; y++) {
        totalDays += isLeapYear(y) ? 366 : 365;
    }
    
    // 计算year年1月到month-1月的总天数
    for (int m = 1; m < month; m++) {
        totalDays += getDaysInMonth(year, m);
    }
    
    return totalDays;
}

void DayTodayDistance() {
    int input_year, input_month, input_day;
    
    // 获取当前日期
    time_t t = time(NULL);
    struct tm tm = *localtime(&t);
    int current_year = tm.tm_year + 1900;
    int current_month = tm.tm_mon + 1;
    int current_day = tm.tm_mday;
    
    // 获取用户输入
    printf("请输入日期(年 月 日，用空格分隔): ");
    scanf("%d %d %d", &input_year, &input_month, &input_day);
    
    // 计算两个日期的总天数
    long input_total = getTotalDays(input_year, input_month)+input_day;
    long current_total = getTotalDays(current_year, current_month)+current_day;
    long diff = input_total - current_total;
    
    // 输出结果
    printf("%d %d %d 比今天(%d-%d-%d) ", 
           input_year, input_month, input_day, 
           current_year, current_month, current_day);
    
    if (diff < 0) {
        printf("早 【%ld】 天\n", -diff);
    } else if (diff > 0) {
        printf("晚 【%ld】 天\n", diff);
    } else {
        printf("就是今天\n");
    }
}
void DayDayDistance()
{
    int y1,m1,d1,y2,m2,d2;
    long t;
	printf("请输入第一个日期（YYYY MM DD）：");
    scanf("%d %d %d", &y1, &m1, &d1);
    printf("请输入第二个日期（YYYY MM DD）：");
    scanf("%d %d %d", &y2, &m2, &d2);
	long days1 = getTotalDays(y1, m1)+d1;
    long days2 = getTotalDays(y2, m2)+d2;
    t=(days1 > days2 ? (days1 - days2) : (days2 - days1));
	printf("两天之间的天数差为：%ld 天\n",t );
}
// 打印月历
void Month(int year, int month) {
    printf("     %d年%d月\n", year, month);
    printf("日 一 二 三 四 五 六\n");
    
    // 计算该月1日是星期几 (0=周日, 1=周一, ..., 6=周六)
    int firstDayOfWeek = (getTotalDays(year, month) + 1) % 7;
    
    // 打印前面的空格
    for (int i = 0; i < firstDayOfWeek; i++) {
        printf("   ");
    }
    
    int daysInMonth = getDaysInMonth(year, month);
    
    // 打印日期
    for (int day = 1; day <= daysInMonth; day++) {
        printf("%2d ", day);
        
        // 如果是周六或者月末，换行
        if ((firstDayOfWeek + day) % 7 == 0 || day == daysInMonth) {
            printf("\n");
        }
    }
}
// 公历转农历
void solarToLunar(int year, int month, int day, LunarDate *lunar) {
    
    lunar->year = year;
    lunar->month = month - 1;
    if (lunar->month <= 0) {
        lunar->month += 12;
        lunar->year -= 1;
    }
    lunar->day = day;
    lunar->isLeapMonth = 0;
    
    // 调整日期范围
    if (lunar->day > 30) lunar->day = 30;
    if (lunar->month > 12) lunar->month = 12;
}
// 获取天干地支
void getGanZhi(int year, int month, int day, char *ganzhi) {
    // 天干地支计算
    static const char *tiangan[] = {"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"};
    static const char *dizhi[] = {"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"};
    
    // 计算年柱
    int ganIndex = (year - 4) % 10;
    int zhiIndex = (year - 4) % 12;
  
    // 组合结果
    sprintf(ganzhi, "年柱: %s%s", 
            tiangan[ganIndex], dizhi[zhiIndex]);
}
// 计算指定天数后的日期
void calculate_date(int days, int *year, int *month, int *day) {
    // 处理负天数（过去日期）
    int direction = days < 0 ? -1 : 1;
    days = days < 0 ? -days : days;
    
    while (days > 0) {
        *day += direction;
        
        // 处理跨月
        if (*day < 1) {
            (*month)--;
            if (*month < 1) {
                *month = 12;
                (*year)--;
            }
            *day = getDaysInMonth(*year, *month);
        } 
        // 处理跨月
        else if (*day > getDaysInMonth(*year, *month)) {
            *day = 1;
            (*month)++;
            if (*month > 12) {
                *month = 1;
                (*year)++;
            }
        }
        
        days--;
    }
}

// 获取星期几的名称
const char* get_weekday_name(int year, int month, int day) {
    static const char* weekdays[] = {"日", "一", "二", "三", "四", "五", "六"};
    
    if (month < 3) {
        month += 12;
        year--;
    }
    
    int c = year / 100;
    int y = year % 100;
    
    int w = (y + y/4 + c/4 - 2*c + 26*(month+1)/10 + day - 1) % 7;
    w = (w + 7) % 7;
    
    return weekdays[w];
}

int Todaydistancedate() {
    int days;
    
    // 获取当前日期
    time_t t = time(NULL);
    struct tm tm = *localtime(&t);
    int current_year = tm.tm_year + 1900;
    int current_month = tm.tm_mon + 1;
    int current_day = tm.tm_mday;
    
    // 获取用户输入的天数
    printf("请输入天数: ");
    scanf("%d", &days);
    
    // 计算未来日期
    int future_year = current_year;
    int future_month = current_month;
    int future_day = current_day;
    calculate_date(days, &future_year, &future_month, &future_day);
    
    // 计算过去日期
    int past_year = current_year;
    int past_month = current_month;
    int past_day = current_day;
    calculate_date(-days, &past_year, &past_month, &past_day);
    
    // 输出结果
    printf("距离今天 (%d-%d-%d) 【%d】 天的日期为:\n", 
           current_year, current_month, current_day, days);
     printf("未来日期: %d-%d-%d 星期%s\n", 
           future_year, future_month, future_day, 
           get_weekday_name(future_year, future_month, future_day));
    
    printf("过去日期: %d-%d-%d 星期%s\n", 
           past_year, past_month, past_day, 
           get_weekday_name(past_year, past_month, past_day));
           return 0;
       }
    
 


// 设置控制台文本颜色
void setColor(int color) {
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
}

// 显示公历节日
void showSolarFestivals(int month)
 {
    // 公历节日数据
    SolarFestival festivals[] = {
        {1, 1, "元旦"},
        {2, 14, "情人节"},
        {3, 8, "国际妇女节"},
        {3, 12, "植树节"},
        {4, 1, "愚人节"},
        {5, 1, "劳动节"},
        {5, 4, "五四青年节"},
        {6, 1, "国际儿童节"},
        {7, 1, "建党节"},
        {8, 1, "建军节"},
        {9, 10, "教师节"},
        {10, 1, "国庆节"},
        {12, 25, "圣诞节"}
    };
    
    int count = sizeof(festivals) / sizeof(festivals[0]);
    int found = 0;
    
    setColor(FOREGROUND_GREEN);
    printf("\n=== 公历%d月节日 ===\n", month);
    setColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
    
    for (int i = 0; i < count; i++) {
        if (festivals[i].month == month) {
            printf("%d月%d日: %s\n", festivals[i].month, festivals[i].day, festivals[i].name);
            found = 1;
        }
    }
    
    if (!found) {
        printf("该月份没有公历节日\n");
    }
}

// 显示农历节日
void showLunarFestivals() {
    // 农历节日数据
    LunarFestival festivals[] = {
        {1, 1, "春节"},
        {1, 15, "元宵节"},
        {5, 5, "端午节"},
        {7, 7, "七夕节"},
        {8, 15, "中秋节"},
        {9, 9, "重阳节"},
        {12, 8, "腊八节"},
        {12, 23, "小年"}
    };
    
    int count = sizeof(festivals) / sizeof(festivals[0]);
    
    setColor(FOREGROUND_GREEN);
    printf("\n=== 农历节日 ===\n");
    setColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
    
    for (int i = 0; i < count; i++) {
        printf("农历%d月%d日: %s\n", festivals[i].month, festivals[i].day, festivals[i].name);
    }
}

int Festival() {
    int choice, month;
    
    // 设置控制台标题
    SetConsoleTitle("节日查询系统");
     while (1) {
        setColor(FOREGROUND_GREEN | FOREGROUND_INTENSITY);
        printf("\n===== 节日查询系统 =====\n");
        setColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
        printf("1. 查询公历节日\n");
        printf("2. 查询农历节日\n");
        printf("0. 退出系统\n");
        printf("请输入选择(0-2): ");
        scanf("%d", &choice);
        
        switch (choice) {
            case 1:
                printf("请输入要查询的月份(1-12): ");
                scanf("%d", &month);
                if (month < 1 || month > 12) {
                    setColor(FOREGROUND_RED);
                    printf("输入错误！月份必须在1-12之间\n");
                    setColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
                    break;
                }
                showSolarFestivals(month);
                break;
            case 2:
                showLunarFestivals();
                break;
            case 0:
                setColor(FOREGROUND_GREEN);
                printf("\n感谢使用节日查询系统，再见！\n");
                setColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
                return 0;
            default:
                setColor(FOREGROUND_RED);
                printf("输入错误！请重新输入\n");
                setColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
        }
    }
    
    return 0;
}

// 获取公历月份的天数
int GetGregorianMonthDays(int year, int month) {
    if (month == 2) {
        return isLeapYear(year) ? 29 : 28;
    }
    return gregorianMonthDays[month - 1];
}
// 检查输入的农历日期是否有效
bool IsValidLunarDate(int year, int month, int day) {
    // 检查年份范围
    if (year < 2000 || year > 2050) {
        printf("年份超出范围(2000-2050)!\n");
        return false;
    }
    
    // 检查月份范围
    if (month < 1 || month > 12) {
        printf("月份超出范围(1-12)!\n");
        return false;
    }
    
    // 检查日范围
    if (day < 1 || day > 30) {
        printf("日超出范围(1-30)!\n");
        return false;
    }
    
    // 查找年份信息
    LunarYearInfo* info = NULL;
    for (int i = 0; lunarYearTable[i].year != 0; i++) {
        if (lunarYearTable[i].year == year) {
            info = &lunarYearTable[i];
            break;
        }
    }
    
    if (info == NULL) {
        printf("找不到该农历年份的信息!\n");
        return false;
    }
    
    // 检查月份是否有效
    if (month > info->monthCount) {
        printf("该农历年份没有%d月!\n", month);
        return false;
    }
    
    // 检查日是否有效
    if (day > info->monthDays[month - 1]) {
        printf("该农历月份没有%d日!\n", day);
        return false;
    }
    
    return true;
}
// 获取天干地支年份
void GetGanZhiYear(int lunarYear, char* ganZhi) {
    // 天干地支以1864年(甲子年)为基准
    int baseYear = 1864;
    int offset = (lunarYear - baseYear) % 60;
    if (offset < 0) offset += 60;
    
    int ganIndex = offset % 10;
    int zhiIndex = offset % 12;
    
    sprintf(ganZhi, "%s%s", TianGan[ganIndex], DiZhi[zhiIndex]);
}
// 农历日期查询公历日期
bool GetGre(int lunarYear, int lunarMonth, int lunarDay, int* greYear, int* greMonth, int* greDay) {
    // 查找年份信息
    LunarYearInfo* info = NULL;
    for (int i = 0; lunarYearTable[i].year != 0; i++) {
        if (lunarYearTable[i].year == lunarYear) {
            info = &lunarYearTable[i];
            break;
        }
    }
    
    if (info == NULL) {
        printf("找不到该农历年份的信息!\n");
        return false;
    }
    
    // 计算从正月初一到目标日期的总天数
    int totalDays = 0;
    for (int i = 0; i < lunarMonth - 1; i++) {
        totalDays += info->monthDays[i];
    }
    totalDays += lunarDay - 1;  // 减去1因为正月初一是第0天
    
    // 初始化公历日期为正月初一对应的日期
    *greYear = lunarYear;
    *greMonth = info->newYearMonth;
    *greDay = info->newYearDay;
    
    // 添加总天数，正确处理月份和年份的跨越
    while (totalDays > 0) {
        int daysInMonth = GetGregorianMonthDays(*greYear, *greMonth);
        int daysToAdd = (totalDays > (daysInMonth - *greDay)) ? (daysInMonth - *greDay + 1) : totalDays;
        
        *greDay += daysToAdd;
        totalDays -= daysToAdd;
        
        if (*greDay > daysInMonth) {
            *greDay = 1;
            (*greMonth)++;
            
            if (*greMonth > 12) {
                *greMonth = 1;
                (*greYear)++;
            }
        }
    }
    
    return true;
}
// 显示主菜单
void ShowMainMenu() {
    printf("\n========== 农历转公历查询系统 ==========\n");
    printf("1. 查询公历日期\n");
    printf("2. 退出系统\n");
    printf("=======================================\n");
    printf("请输入选项(1-2): ");
}
// 农历转公历查询功能
void LunarToGregorian() {
    int lunarYear, lunarMonth, lunarDay;
    
    printf("\n========== 农历转公历查询 ==========\n");
    printf("请输入农历日期(年 月 日, 2000-2050): ");
    
    if (scanf("%d %d %d", &lunarYear, &lunarMonth, &lunarDay) != 3) {
        printf("输入格式错误!\n");
        while (getchar() != '\n'); 
        return;
    }
    
    // 验证输入的农历日期
    if (!IsValidLunarDate(lunarYear, lunarMonth, lunarDay)) {
        return;
    }
    
    // 获取天干地支年份
    char ganZhi[10];
    GetGanZhiYear(lunarYear, ganZhi);
    
    // 显示农历日期信息
    printf("\n农历日期: %d年(%s) %d月 %d日\n", lunarYear, ganZhi, lunarMonth, lunarDay);
    
    // 查询对应的公历日期
    int greYear, greMonth, greDay;
    if (GetGre(lunarYear, lunarMonth, lunarDay, &greYear, &greMonth, &greDay)) {
        printf("对应的公历日期: %d年 %d月 %d日\n", greYear, greMonth, greDay);
    } else {
        printf("无法计算对应的公历日期!\n");
    }
}